package com.authenticateCenter.event;


import cn.hutool.extra.spring.SpringUtil;
import com.authenticateCenter.domain.entity.User;
import com.authenticateCenter.service.IUserRoleService;
import com.dhy.canal.CanalMessageListener;
import com.dhy.canal.CanalTable;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 利用canal监听领域事件表的变化
 * @author 大忽悠
 * @create 2022/12/22 15:23
 */
@Component
@Slf4j
@CanalTable("domain_event")
public class DomainEventHandler implements CanalMessageListener<DomainEvent> {
    public static final String USER_REGISTER_EVENT="u_register";
    public static final String USER_UPDATE_EVENT="u_update";
    public static final String USER_DEL_EVENT="u_del";
    private static final Map<String,DomainEventProcessor> processorMap=new HashMap<>();
    private static final ObjectMapper objectMapper=new ObjectMapper();

    static {
        processorMap.put(USER_DEL_EVENT,(e,m,u)->{
            u.delByName(String.valueOf(m.get("username")));
        });
        processorMap.put(USER_REGISTER_EVENT,(e,m,u)->{
            User user = User.builder().username(String.valueOf(m.get("username"))).build();
            user.insertCheck(u);
            u.save(user);
            IUserRoleService ur = SpringUtil.getBean(IUserRoleService.class);
            ur.releaseAuthorityToRoleByNameList(user.getId(), List.of(((String) m.get("roles")).split(",")));
        });
        processorMap.put(USER_UPDATE_EVENT,(e,m,u)->{
            u.updateName((String) m.get("oldUsername"), (String) m.get("newUsername"));
        });
    }

    @Transactional
    @Override
    public void insert(DomainEvent domainEvent) {
        log.info("监听到领域事件: {}",domainEvent);
        //忽略无法识别的领域事件
        DomainEventProcessor eventProcessor = processorMap.get(domainEvent.getEventDesc());
        if(eventProcessor!=null){
            eventProcessor.processEvent(domainEvent,objectMapper);
        }
    }
}
